package com.jzo2o.customer.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.CurrentUserInfo;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.customer.enums.AuditStatusEnum;
import com.jzo2o.customer.enums.CertificationStatusEnum;
import com.jzo2o.customer.mapper.AgencyCertificationAuditMapper;
import com.jzo2o.customer.mapper.AgencyCertificationMapper;
import com.jzo2o.customer.mapper.ServeProviderMapper;
import com.jzo2o.customer.mapper.WorkerCertificationMapper;
import com.jzo2o.customer.model.domain.*;
import com.jzo2o.customer.model.dto.request.AgencyCertificationAuditPageQueryReqDTO;
import com.jzo2o.customer.model.dto.response.AgencyCertificationAuditResDTO;
import com.jzo2o.customer.model.dto.response.RejectReasonResDTO;
import com.jzo2o.customer.model.dto.response.WorkerCertificationAuditResDTO;
import com.jzo2o.customer.service.IAgencyCertificationAuditService;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 机构认证审核 服务实现类
 */
@Service
public class AgencyCertificationAuditServiceImpl extends ServiceImpl<AgencyCertificationAuditMapper, AgencyCertificationAudit> implements IAgencyCertificationAuditService {
    @Resource
    private AgencyCertificationMapper agencyCertificationMapper;
    @Resource
    private ServeProviderMapper serveProviderMapper;


    /**
     * 机构端 - 查询最新驳回原因
     *
     * @return 最新驳回原因
     */
    @Override
    @SuppressWarnings("unchecked")
    public RejectReasonResDTO getLatestRejectReason() {
        //1、获取当前登录用户的id
        Long userId = UserContext.currentUserId();
        //2、判断当前登录用户是否存在
        if (ObjectUtils.isEmpty(userId)) {
            throw new ForbiddenOperationException("机构不存在无法查询");
        }
        //3、查询当前登录用户最新的认证审核记录
        List<AgencyCertificationAudit> certificationAudits = lambdaQuery()
                .eq(AgencyCertificationAudit::getCertificationStatus, CertificationStatusEnum.FAIL.getStatus()) //认证失败
                .eq(AgencyCertificationAudit::getServeProviderId, userId)
                .orderByDesc(AgencyCertificationAudit::getCreateTime) // 最新创建时间
                .list();
        //4、返回最新驳回原因
        return CollUtils.isEmpty(certificationAudits)
                ? new RejectReasonResDTO()
                : new RejectReasonResDTO(certificationAudits.get(0).getRejectReason());
    }

    /**
     * 运营端 - 审核机构认证-分页查询
     *
     * @param pageQueryReqDTO 查询参数
     * @return 机构认证审核列表
     */
    @Override
    public PageResult<AgencyCertificationAuditResDTO> queryPage(AgencyCertificationAuditPageQueryReqDTO pageQueryReqDTO) {
        // 1、 将前端传递的分页参数（DTO）解析为MP的Page对象（含页码、页大小、排序规则）
        Page<AgencyCertificationAudit> pageQuery = PageUtils.parsePageQuery(pageQueryReqDTO, AgencyCertificationAudit.class);

        // 2、 构建查询条件 - 通过 Wrappers 工具类静态方法创建，一步链式完成（创建 + 加条件）
        String name = pageQueryReqDTO.getName(); // 企业名称
        String idCardNo = pageQueryReqDTO.getLegalPersonName(); // 法人姓名
        Integer auditStatus = pageQueryReqDTO.getAuditStatus(); // 审核状态
        Integer certificationStatus = pageQueryReqDTO.getCertificationStatus(); // 认证状态
        LambdaQueryWrapper<AgencyCertificationAudit> queryWrapper = Wrappers.<AgencyCertificationAudit>lambdaQuery()
                .like(ObjectUtils.isNotEmpty(name), AgencyCertificationAudit::getName, name)
                .like(ObjectUtils.isNotEmpty(idCardNo), AgencyCertificationAudit::getLegalPersonName, idCardNo)
                .eq(ObjectUtils.isNotEmpty(auditStatus), AgencyCertificationAudit::getAuditStatus, auditStatus)
                .eq(ObjectUtils.isNotEmpty(certificationStatus), AgencyCertificationAudit::getCertificationStatus, certificationStatus);

        // 3、 调用MP的默认分页查询方法：根据page（分页参数）和queryWrapper（筛选条件）执行SQL
        // 执行后，page对象会自动填充总条数、总页数、当前页数据等信息
        return PageUtils.toPage(
                baseMapper.selectPage(pageQuery, queryWrapper),
                AgencyCertificationAuditResDTO.class);
    }


    /**
     * 运营端 - 审核机构认证信息
     *
     * @param id                  认证记录id
     * @param certificationStatus 认证状态
     * @param rejectReason        拒绝原因
     */
    @Override
    public void audit(Long id, Integer certificationStatus, String rejectReason) {
        //1、根据id查询认证记录
        AgencyCertificationAudit agencyCertificationAudit = baseMapper.selectById(id);
        if (ObjectUtils.isEmpty(agencyCertificationAudit)) {
            throw new ForbiddenOperationException("认证记录不存在无法审核");
        }
        //2、通过ThreadLocal获取当前登录的用户信息
        CurrentUserInfo currentUserInfo = UserContext.currentUser();
        if (ObjectUtils.isEmpty(currentUserInfo) || ObjectUtils.isEmpty(currentUserInfo.getId())) {
            throw new ForbiddenOperationException("无法获取当前用户信息");
        }

        //3、准备审核人相关-公共部分的数据
        LocalDateTime now = LocalDateTime.now(); // 当前时间
        agencyCertificationAudit.setCertificationStatus(certificationStatus); // 认证状态
        //构建更新条件 - 更新 agency_certification_audit表
        LambdaUpdateChainWrapper<AgencyCertificationAudit> updateChainWrapper = lambdaUpdate()
                .eq(AgencyCertificationAudit::getId, id) // 认证记录id
                .set(AgencyCertificationAudit::getAuditStatus, AuditStatusEnum.AUDITED.getStatus()) // 审核状态设为已审核
                .set(AgencyCertificationAudit::getAuditTime, now) // 审核时间设为当前时间
                .set(AgencyCertificationAudit::getAuditorId, currentUserInfo.getId()) // 审核人设为当前登录用户
                .set(AgencyCertificationAudit::getAuditorName, currentUserInfo.getName()) // 审核人名称设为当前登录用户名称
                .set(AgencyCertificationAudit::getCertificationStatus, certificationStatus); // 认证状态设为-前端给的认证状态

        //4、根据认证状态进行不同处理
        String name = ""; //用来保存姓名
        //获取机构id
        Long serveProviderId = agencyCertificationAudit.getServeProviderId();
        //4.1、认证失败
        if (certificationStatus == CertificationStatusEnum.FAIL.getStatus()) {
            //更新拒绝原因
            updateChainWrapper
                    .set(AgencyCertificationAudit::getRejectReason, rejectReason) // 拒绝原因设为-前端给的拒绝原因
                    .update();
            //机构认证失败 - 对 agency_certification 表进行认证失败更新
            agencyCertificationMapper.updateById(AgencyCertification.builder()
                    .id(serveProviderId) //服务人员id
                    .certificationStatus(certificationStatus) //认证状态设为-认证失败
                    .certificationTime(now) //认证时间设为当前时间
                    .build());
        } else {
            //4.2、认证成功
            updateChainWrapper
                    .update();

            // 机构认证成功 - 对agency_certification 表进行完整数据填充
            agencyCertificationMapper.updateById(AgencyCertification.builder()
                    .id(serveProviderId)
                    .name(agencyCertificationAudit.getName())
                    .idNumber(agencyCertificationAudit.getIdNumber())
                    .legalPersonName(agencyCertificationAudit.getName())
                    .legalPersonIdCardNo(agencyCertificationAudit.getLegalPersonIdCardNo())
                    .businessLicense(agencyCertificationAudit.getBusinessLicense())
                    .certificationStatus(certificationStatus)
                    .certificationTime(now).build());
            name = agencyCertificationAudit.getName();
        }

        // 更新总表中机构的姓名
        ChainWrappers.lambdaUpdateChain(serveProviderMapper)
                .eq(ServeProvider::getId, serveProviderId)
                .set(ServeProvider::getName, name)
                .update();
    }
}
